package com.onesports.intelligent.k12.polarlight.security;

import com.onesports.intelligent.k12.polarlight.service.sys.MenuService;
import com.onesports.intelligent.k12.polarlight.service.sys.ResourceService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @author: aj
 */
@Component
public class CustomSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Resource
    private ResourceService resourceService;

    @Value("${server.servlet.context-path}")
    private String contextPath;

    private Map<String, Collection<ConfigAttribute>> map = null;

    /**
     * 判定当前请求对应的资源权限
     * 如果在权限表中，则返回给decide方法，用来判定用户是否有此权限
     * 如果不在权限表中则放行
     *
     * @param o
     * @return
     * @throws IllegalArgumentException
     */
    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
        Collection<ConfigAttribute> configAttributes = new ArrayList<>();
        String systemCode = SecurityUtils.getSystemCode();
        boolean isSuper = SecurityUtils.isSuper();
        List<com.onesports.intelligent.k12.polarlight.domain.entity.sys.Resource>
                resources = resourceService.getAllList();

        //Object中包含用户请求request
        String method = ((FilterInvocation) o).getHttpRequest().getMethod();
        String requestURI = ((FilterInvocation) o).getRequest().getRequestURI();
        requestURI = requestURI.endsWith("/") ? requestURI.substring(0, requestURI.length() - 1) : requestURI;
        String finalRequestURI = requestURI;
        PathMatcher pathMatcher = new AntPathMatcher();
        final String prefix = StringUtils.isNoneBlank(contextPath)
                && !"/".equals(contextPath) ? contextPath : "";
        if (isSuper && StringUtils.isNotEmpty(systemCode)) {
            List<com.onesports.intelligent.k12.polarlight.domain.entity.sys.Resource>
                    superResources = resourceService.listBySystemCode(systemCode);
            for (com.onesports.intelligent.k12.polarlight.domain.entity.sys.Resource
                    resource : superResources) {
                String uri = resource.getResourceUri();
                uri = uri.startsWith("/") ? prefix + uri : prefix + "/" + uri;
                if (resource.getResourceMethod().equals(method) &&
                        pathMatcher.match(uri, finalRequestURI)) {
                    return configAttributes;
                }
            }
        }
        resources.stream().filter(resource -> {
                    String uri = resource.getResourceUri();
                    uri = uri.startsWith("/") ? prefix + uri : prefix + "/" + uri;
                    return resource.getResourceMethod().equals(method) &&
                            pathMatcher.match(uri, finalRequestURI);
                })
                .forEach(resource -> {
                    configAttributes.add(new SecurityConfig(String.valueOf(resource.getId())));
                });

        return configAttributes;
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        //所有定义的权限资源
        // 启动时校验每个ConfigAttribute是否配置正确，不需要校验直接返回null
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        //FilterInvocation
        return true;
    }

}
